#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>

using std::cout;
using std::endl;
using std::map;
using std::string;
using std::ifstream;
using std::ofstream;
using std::istringstream;

struct Record
{
    Record(const string & w, int freq)
    : _word(w)
    , _frequency(freq)
    {}

    string _word;
    int _frequency;
};

class Dictionary
{
public:
    Dictionary()
    {}

    void read(const string & filename);
    void store(const string & filename);

private:
    //当参数形式是非const引用时，意味着会对他进行修改
    void preprocess(string & w);
    void wordStatistic(const string & w);

private:
    map<string, int> _dict;
};

void Dictionary::preprocess(string & w)
{
    //如果发现其中有字符不是字母，就直接忽略掉该单词
    //如果发现其中有字符是大写字母，就改写小写字母
    for(int i = 0; i < w.size(); ++i) {
        if(!isalpha(w[i])) {
            w=string();
            break;
        }
        if(isupper(w[i])) {
            w[i] = tolower(w[i]);
        }
    }
}

void Dictionary::wordStatistic(const string & w)
{
    //如果单词存在，就将其词频加1
    //如果单词不存在，就添加新的记录，并将其词频设置为1
    ++_dict[w];
#if 0
    auto iter = _dict.find(w);
    if(iter == _dict.end()) {
        _dict.insert({w, 1});
    } else {
        ++iter->second;
    }
#endif
#if 0
    //对词典中的每一个元素进行遍历
    int i = 0;
    for(; i < _dict.size(); ++i) {
        if(_dict[i]._word == w) {
            _dict[i]._frequency++;
            break;
        }
    }

    //在_dict中没有找到w
    if(i == _dict.size()) {
        _dict.push_back(Record(w, 1));
    }
#endif
}

void Dictionary::read(const string & filename)
{
    ifstream ifs(filename);
    if(!ifs.good()) {
        cout << "ifstream open file " << filename << " error" << endl;
        return;
    }
    //每次处理一行
    string line;
    string word;
    while(!ifs.eof()) {
        getline(ifs, line);
        istringstream iss(line);//将一行数据保存到字符串输入流中
        //iss >> word 默认是用空格分隔每一个单词
        while(iss >> word) {
            //预处理每一个单词
            preprocess(word);
            cout << word << endl;
            //进行词频统计操作
            wordStatistic(word);
        }
    }

    ifs.close();
}

void Dictionary::store(const string & filename)
{
    ofstream ofs(filename);
    if(!ofs.good()) {
        cout << "ofstream open file " << filename << " error" << endl;
        return;
    }

    //遍历_dict，写入到文件中
    for(auto & record : _dict) {
        ofs << record.first << " " << record.second << endl;
    }

    ofs.close();
}

int main()
{
    Dictionary dict;
    dict.read("The_Holy_Bible.txt");
    dict.store("dict.txt");

    return 0;
}

